/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package poker.cards;

import java.util.ArrayList;
import java.util.Collections;

/**
 *
 * @author Norteromius
 */
public class CardsSet
{

    private ArrayList<Card> cardsSet = new ArrayList<Card>();
    private String Kind = "";
    private int Value;
    public ArrayList<Integer> listOfFirst = new ArrayList<Integer>();   // I lista powtarzajacych sie kart (indeksy)
    public ArrayList<Integer> listOfSecond = new ArrayList<Integer>();  // II lista powtarzajacych sie kart (indeksy)

    public CardsSet()
    {
    }

    /**
     *  Sortuje karty i sprawdza stan
     */ 
    public CardsSet(ArrayList<Card> cardsSet)
    {
       
        this.cardsSet = cardsSet;
        Collections.sort(this.cardsSet);
        
        this.countValueOfSet();
    }
    
    /**
     * Zwraca karte bedaca na pozycji 'index' w zbiorze 'cardSet'
     */
    public Card getCardAt(int index)
    {
        return cardsSet.get(index);
    }

    /**
     * Okreslanie ukladu, jaki obecnie jest w kartach
     */
    private void countValueOfSet()
    {

        boolean isSetChosen = checkStraight();
        boolean isColorChosen = checkSetColor();
        
        // gdy mamy straight i kolor i najnizsza karta to 10
        if (isSetChosen && isColorChosen && "10".equals(cardsSet.get(0).getKind()))
        {
            this.Kind = CardsConstants.KEY_SET_ROYAL;
            this.Value = CardsConstants.KEY_SET_VALUE_ROYAL;
            return;
        }
        // w przypadku, gdy mamy i straight i kolor = poker
        if (isSetChosen && isColorChosen)
        {
            this.Kind = CardsConstants.KEY_SET_POKER;
            this.Value = CardsConstants.KEY_SET_VALUE_POKER;
            return;
        }
        if (isColorChosen)
        {
            this.Kind = CardsConstants.KEY_SET_FLUSH;
            this.Value = CardsConstants.KEY_SET_VALUE_FLUSH;
            return;
        }
        if (isSetChosen)
        {
            this.Kind = CardsConstants.KEY_SET_STRAIGHT;
            this.Value = CardsConstants.KEY_SET_VALUE_STRAIGHT;
            return;
        }
        if (checkSetKindOfCards())
        {
            return;
        } else
        {
            this.Kind = CardsConstants.KEY_SET_NOTHING;
            this.Value = CardsConstants.KEY_SET_VALUE_NOTHING;
        }
    }

    /**
     * Sprawdza, czy wszystkie karty w ukladzie sa jednego koloru
     * @return 
     */
    private boolean checkSetColor()
    {
        boolean allInOne = true;
        for (int i = 0; i < this.cardsSet.size() - 1; i++)
        {
            if (!this.cardsSet.get(i).getColor().equalsIgnoreCase(this.cardsSet.get(i + 1).getColor()))
            {
                allInOne = false;
                break;
            }
        }
        return allInOne;
    }

    /**
     * Sprawdzenie ukladow z rodzaju kart:
     * para, dwie pary, trojka, full, kareta
     */
    private boolean checkSetKindOfCards()
    {
        boolean isChosen = false;
        ArrayList[] array = new ArrayList[15];          // tablica list indeksow kart
        for (int i = 0; i < 15; i++)
            array[i] = new ArrayList<Integer>();

       
        for (int i = 0; i < this.cardsSet.size(); i++)
        {
            array[this.cardsSet.get(i).getCountInKind()].add(i);
        }
        
        for (int i = 0; i < 15; i++)
        {
            if (array[i].size() >= 2 && listOfFirst.isEmpty())
            {
                listOfFirst = array[i];
            }
            else if (array[i].size() >= 2 && !listOfFirst.isEmpty())
            {
                listOfSecond = array[i];
            }
        }

        // listOfFirst musi byc nie wieksze niz listOfSecond
        if (listOfFirst.size() > listOfSecond.size())
        {
            ArrayList<Integer> temp = listOfFirst;
            listOfFirst = listOfSecond;
            listOfSecond = temp;
        }
        
        if (listOfFirst.size() <= 1)
        {
            if (listOfSecond.size() == 2)
            {
                this.Kind = CardsConstants.KEY_SET_PAIR;
                this.Value = CardsConstants.KEY_SET_VALUE_PAIR;
                return isChosen = true;
            } else if (listOfSecond.size() == 3)
            {
                this.Kind = CardsConstants.KEY_SET_THREE_OF_KIND;
                this.Value = CardsConstants.KEY_SET_VALUE_THREE_OF_KIND;
                return isChosen = true;
            } else if (listOfSecond.size() == 4)
            {
                this.Kind = CardsConstants.KEY_SET_FOUR_OF_KIND;
                this.Value = CardsConstants.KEY_SET_VALUE_FOUR_OF_KIND;
                return isChosen = true;
            }
        } 
                
        if (listOfFirst.size() == 2)
        {

            if (listOfSecond.size() == 2)
            {
                this.Kind = CardsConstants.KEY_SET_TWO_PAIRS;
                this.Value = CardsConstants.KEY_SET_VALUE_TWO_PAIRS;
                return isChosen = true;
            } else if (listOfSecond.size() == 3)
            {
                this.Kind = CardsConstants.KEY_SET_FULL_OF_HOUSE;
                this.Value = CardsConstants.KEY_SET_VALUE_FULL_OF_HOUSE;
                return isChosen = true;
            }
        }
 
        return isChosen;
    }

    /**
     * sprawdza, czy jest straight w ukladzie
     * @return 
     */
    private boolean checkStraight()
    {

        for (int i = 0; i < this.cardsSet.size() - 1; i++)
        {
            if (this.cardsSet.get(i).getCountInKind() != (this.cardsSet.get(i + 1).getCountInKind() - 1))
            {
                return false;
            }
        }
        return true;

    }

    public ArrayList<Card> getCardsSet()
    {
        return cardsSet;
    }
    
    public String getCardsSetNice()
    {
        String out = "";
        for (int i = 0; i < 5; i++)
        {
            out += cardsSet.get(i) + " ";
        }
        return out;
    }

    public void setCardsSet(ArrayList<Card> cardsSet)
    {
        this.cardsSet = cardsSet;
    }

    public String getKind()
    {
        return Kind;
    }

    public void setKind(String setKind)
    {
        this.Kind = setKind;
    }

    public int getValue()
    {
        return Value;
    }

    public void setValue(int setValue)
    {
        this.Value = setValue;
    }
}
